﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Kakaroto.Models;

namespace Kakaroto.Pedidos
{
    public class PedidoActions : IDisposable
    {
        public string IdPedido { get; set; }
        private KakarotoEntities _db = new KakarotoEntities();

        public string GetIdPedido()
        {
            if (HttpContext.Current.Session["IdPedido"] == null)
            {
                HttpContext.Current.Session["IdPedido"] = Guid.NewGuid().ToString();
            }
            return HttpContext.Current.Session["IdPedido"].ToString();
        }

        public void AdicionaProduto(int id, int qtdd, string observacao)
        {

            try
            {
                IdPedido = GetIdPedido();
                List<ItemPedido> itensPedido = HttpContext.Current.Session["ItensPedido"] as List<ItemPedido>;
                if (itensPedido == null)
                {
                    itensPedido = new List<ItemPedido>();
                }

                var itemPedido = itensPedido.FirstOrDefault(ip => ip.Id_Ped == IdPedido 
                        && ip.Id_Prod == id
                        && ip.Observacao == observacao
                        && ip.Pronto == null
                    );
                
                if (itemPedido == null || itemPedido.Pronto != null || itemPedido.Observacao != observacao)
                {
                    itemPedido = new ItemPedido
                    {
                        Id = Guid.NewGuid().ToString(),
                        Id_Ped = IdPedido,
                        Id_Prod = id,
                        Produto = _db.Produto.FirstOrDefault(p => p.Id == id),
                        Preco = _db.Produto.SingleOrDefault(p => p.Id == id).Preco,
                        Qtdd = qtdd,
                        Observacao = observacao,
                        Hora = DateTime.Now
                    };
                }
                else
                {
                    itensPedido.Remove(itemPedido);
                    itemPedido.Qtdd += qtdd;
                }
                itensPedido.Add(itemPedido);
                HttpContext.Current.Session["ItensPedido"] = itensPedido;
            }
            catch (Exception exp)
            {
                throw new Exception("Erro: impossível adicionar produto - " + exp.Message.ToString(), exp);
            }
        }
        
        public decimal GetTotal()
        {
            IdPedido = GetIdPedido();
            List<ItemPedido> itensPedido = HttpContext.Current.Session["ItensPedido"] as List<ItemPedido>;

            decimal? total = decimal.Zero;
            foreach (ItemPedido item in itensPedido)
            {
                total += (decimal?)(item.Preco * item.Qtdd);
            }                
            return total ?? decimal.Zero;
        }

        public string GetMesaPedido()
        {
            return HttpContext.Current.Session["IdMesa"].ToString();
        }

        public void PreparaAtualizacao(string Id_Pedido)
        {
            HttpContext.Current.Session["IdPedido"] = Id_Pedido;
            
            IdPedido = GetIdPedido();
            var pedido = (from p in _db.Pedido where p.Id == IdPedido select p).FirstOrDefault();
            HttpContext.Current.Session["IdMesa"] = pedido.Id_Mesa.ToString();
            
            var itensPedidoDB = (from ip in _db.ItemPedido where ip.Id_Ped == IdPedido select ip);
            HttpContext.Current.Session["ItensPedido"] = itensPedidoDB.ToList();
            HttpContext.Current.Session["ItensEmEdicao"] = itensPedidoDB.Where(ip => ip.Pronto == null).ToList();
        }

        public void RestauraItensDeEdicaoNaoFinalizada()
        {
            if (HttpContext.Current.Session["IdPedido"] != null
                && HttpContext.Current.Session["ItensEmEdicao"] != null)
            {
                IdPedido = GetIdPedido();
                var item = _db.Pedido.Find(IdPedido);
                
                List<ItemPedido> itensPedido = HttpContext.Current.Session["ItensEmEdicao"] as List<ItemPedido>;
                if (itensPedido != null)
                {
                        foreach (var ip in itensPedido)
                        item.ItemPedido.Add(new ItemPedido
                        {
                            Id = Guid.NewGuid().ToString(),
                            Id_Ped = IdPedido,
                            Id_Prod = ip.Id_Prod,
                            Preco = ip.Preco,
                            Qtdd = ip.Qtdd,
                            Observacao = ip.Observacao,
                            Hora = DateTime.Now
                        });
                }
                
                _db.SaveChanges();
                SetAllNull();
            }
        }

        public void RemoveItensEmEdicaoDoBanco()
        {
            IdPedido = GetIdPedido();
            var itensPedidoDB = (from ip in _db.ItemPedido where ip.Id_Ped == IdPedido select ip);
            foreach (var item in itensPedidoDB)
            {
                if (item.Pronto == null)
                {
                    _db.ItemPedido.Remove(item);
                }
            }
            _db.SaveChanges();
        }

        public void CancelarPedido()
        {

            if (HttpContext.Current.Session["IdPedido"] != null && isCancellable())
            {
                IdPedido = GetIdPedido();
                List<ItemPedido> itensPedido = HttpContext.Current.Session["ItensPedido"] as List<ItemPedido>;
            
                var pedido = (from p in _db.Pedido where p.Id == IdPedido select p).FirstOrDefault();
                if (pedido != null)
                {
                    var itens = (from ip in _db.ItemPedido where ip.Id_Ped == IdPedido select ip);
                    foreach(var item in itens){
                        _db.ItemPedido.Remove(item);
                    }
                    _db.Pedido.Remove(pedido);
                    _db.SaveChanges();
                }
                SetAllNull();
            }
        }

        public bool isCancellable()
        {
            List<ItemPedido> itensPedidos = HttpContext.Current.Session["ItensPedido"] as List<ItemPedido>;
            int itens = itensPedidos.Where(ip => ip.Pronto == true || ip.Pronto == false).Count();
            if (itens <= 0)
            {
                return true;
            }
            else return false;
        }

        public void EsvaziaCarrinho()
        {
            IdPedido = GetIdPedido();
            List<ItemPedido> itensPedido = HttpContext.Current.Session["ItensPedido"] as List<ItemPedido>;

            itensPedido.RemoveAll(ip => ip.Id_Ped == IdPedido && ip.Pronto == null);
            HttpContext.Current.Session["ItensPedido"] = itensPedido;
        }

        public void Dispose()
        {
            _db.Dispose();
            _db = null;
        }

        public void SetAllNull()
        {
            HttpContext.Current.Session["ItensPedido"] = null;
            HttpContext.Current.Session["IdPedido"] = null;
            HttpContext.Current.Session["ItensEmEdicao"] = null;
            HttpContext.Current.Session["IdMesa"] = null;
        }

        public void AtualizarPedido(String Id_Pedido, PedidoUpdates[] pedidoUpdates)
        {
                
                int itensCount = pedidoUpdates.Count();
                
                List<ItemPedido> itensPedido = HttpContext.Current.Session["ItensPedido"] as List<ItemPedido>;
                List<string> toRemove = new List<string>();
                List<ItemPedido> toUpdate = new List<ItemPedido>();

                if (itensPedido != null)
                {
                    foreach (var item in itensPedido)
                    {
                        for (int i = 0; i < itensCount; i++)
                        {
                            if (item.Produto.Id == pedidoUpdates[i].IdProduto)
                            {
                                if (pedidoUpdates[i].Quantidade < 1 || pedidoUpdates[i].Remover == true)
                                {
                                    toRemove.Add(item.Id);
                                }
                                else
                                {
                                    item.Qtdd = pedidoUpdates[i].Quantidade;
                                    toUpdate.Add(item);
                                }
                            }
                        }
                    }
                    RemoverItem(toRemove);
                    AtualizarItem(toUpdate);
                }
               
        }

        public void RemoverItem(List<string> toRemove)
        {
                IdPedido = GetIdPedido();
                List<ItemPedido> itensPedido = HttpContext.Current.Session["ItensPedido"] as List<ItemPedido>;

                foreach(string id in toRemove){
                    ItemPedido item = itensPedido.Where(ip => ip.Id == id).FirstOrDefault();
                    if(item != null){
                        itensPedido.Remove(item);
                    }
                }
                HttpContext.Current.Session["ItensPedido"] = itensPedido;
        }

        public void AtualizarItem(List<ItemPedido> toUpdate)
        {
                IdPedido = GetIdPedido();
                List<ItemPedido> itensPedido = HttpContext.Current.Session["ItensPedido"] as List<ItemPedido>;

                foreach(ItemPedido itemToUp in toUpdate){
                    ItemPedido item = itensPedido.Where(ip => ip.Id == itemToUp.Id).FirstOrDefault();
                    if(item != null){
                        itensPedido.Remove(item);
                        itensPedido.Add(itemToUp);
                    }
                }
                HttpContext.Current.Session["ItensPedido"] = itensPedido;
        }

        public struct PedidoUpdates
        {
            public int IdProduto;
            public int Quantidade;
            public bool Remover;
        }
    }
}